package com.example.controller;


import com.alibaba.fastjson.JSONArray;
// import com.example.config.ApplicationContextProvider;
import com.example.config.KieSessionUtils;
import com.example.config.ServiceMQTT;
import com.example.influxdb.InfluxDBConnection;
import com.example.mapper.*;


// import com.example.mapper.infoMapper;
import com.example.pojo.*;

import com.example.pojo.alarm.alarmMessage;
import com.example.pojo.alarm.messageRemind;
import com.example.pojo.dev.icDevState;
import com.example.pojo.dev.icDevPoint;
import com.example.pojo.dev.fmDevInfo;
import com.example.pojo.dev.fmRoominfo;
import com.example.pojo.mqtt.icPointVar;
import com.example.resule.Result;
import com.example.service.AlarmService;
import com.example.util.HttpClientUtil;
import com.example.websocket.WebSocketServerCamera;

import com.example.websocket.WebSocketServerRemind;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.influxdb.dto.QueryResult;

import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.internal.utils.KieHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.FileNotFoundException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @program: yst-runhuayou2
 * @description: 在redis中获取数据
 * @author:fanzhihui
 * @create: 2022-01-14 10:07
 **/
@Component
public class Rundrools implements CommandLineRunner, Runnable {

    //static String deviceclose = "开关机,启停状态,开停状态,运行状态";   //判断是否离线
    static String deviceclose = "启停状态,运行状态";   //判断是否离线
    /**
     * Callback used to run the bean.
     *
     * @param args incoming main method arguments
     * @throws Exception on error
     */
    //因为有类型所以用名字
    static HashMap<String, KieHelper> kieHelper1 = new HashMap<>();
    static InfluxDBConnection influxDBConnection;
    static SimpleDateFormat sdf01 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    static HashMap<String, List<String>> pointNameMap = new HashMap<>();
    static HashMap<String, List<String>> DistinctMap = new HashMap<>();
    static HashMap<String, List<icPointVar>> icVariablesMap = new HashMap<>();
    static HashMap<String, List<icDevPoint>> bind = new HashMap<>();
    static HashMap<Integer, fmRoominfo> fmRoominfoMap = new HashMap<>();
    static HashMap<String, Thread> threadHashMap = new HashMap<>();
    //所有测点
    static List<Object> pointName;
    //存放报警信息 用于自动复位
    static HashMap<String, HashMap<String, String>> alarmhasMap = new HashMap<>();
    static HashMap<String, String> messagehasMap = new HashMap<>();
    static String time1 = new String("06-01");
    static String time2 = new String("12-01");
    static SimpleDateFormat df = new SimpleDateFormat("MM-dd");
    static boolean isFirstin = true;
    static String season = null;
    static Date lastData = null;
    //    @Autowired
//    public AlarmService alarmService;
    static public AlarmService alarmService;

    @Autowired
    public void alarmService(AlarmService alarmService) {
        Rundrools.alarmService = alarmService;
    }

    // @Autowired
    static public AlarmMapper alarmMapper;

    @Autowired
    public void alarmMapper(AlarmMapper alarmMapper) {
        Rundrools.alarmMapper = alarmMapper;
    }

    static public MessageRemindMapper messageRemindMapper;

    @Autowired
    public void messageRemindMapper(MessageRemindMapper messageRemindMapper) {
        Rundrools.messageRemindMapper = messageRemindMapper;
    }

    // @Autowired
    static public PointEqipmentMapper pointEqipmentMapper;

    @Autowired
    public void pointEqipmentMapper(PointEqipmentMapper pointEqipmentMapper) {
        Rundrools.pointEqipmentMapper = pointEqipmentMapper;
    }

    // @Autowired
    static public FileMapper fileMapper;

    @Autowired
    public void fileMapper(FileMapper fileMapper) {
        Rundrools.fileMapper = fileMapper;
    }

    //  @Autowired
    static public infoMapper infoMapper;

    @Autowired
    public void infoMapper(infoMapper infoMapper) {
        Rundrools.infoMapper = infoMapper;
    }

    @Value("${web.upload}")
    private String upload;

    //静态注入ip 用于自动复位调用接口
    static public String ips;

    @Autowired
    public void ip(Rundrools rundrools) {
        Rundrools.ips = resetip;
    }

    @Value("${web.ip}")
    private String resetip;
    @Value("${spring.influx.user}")
    private String userName;
    @Value("${spring.influx.password}")
    private String password;
    @Value("${spring.influx.url}")
    private String url;
    //@Autowired
    static public ServiceMQTT serviceMQTT;
    @Value("${spring.influx.database}")
    private String influxdb;

    @Autowired
    public void serviceMQTT(ServiceMQTT serviceMQTT) {
        Rundrools.serviceMQTT = serviceMQTT;
    }

    //多线程
    static String spotname = null;

    @Override
    public void run(String... args) throws Exception {


        if (kieHelper1 != null) {
            //kieSession
            //kieSession = kieHelper1.build().newKieSession();
        }

        //数据库连接
        //【influxdb赤峰】
        // influxDBConnection = new InfluxDBConnection(userName, password, url, "chifeng", "");
        //【influxdb轻量化测试服务器】
        influxDBConnection = new InfluxDBConnection(userName, password, url, influxdb, "");

//        //获取数据
//        this.data();

        this.updatekieHepler();

    }

    public void data() {

        //去重测点
        pointName = pointEqipmentMapper.typeDistinct("point_name");
        for (Object o : pointName) {
            //多少个绑定的测点
            List<String> pointNameList = pointEqipmentMapper.selectPointNameListByPointName(o.toString());
            pointNameMap.put(o.toString(), pointNameList);
            //多少个去重的测点名
            List<String> Distinct = pointEqipmentMapper.selectDistinctPointNameListByvariName(o.toString());
            DistinctMap.put(o.toString(), Distinct);
            //这个服务有多少变量
            List<icPointVar> icVariables = pointEqipmentMapper.selectbyponitName(o.toString());
            icVariablesMap.put(o.toString(), icVariables);
            //测点绑定的全部内容
            List<icDevPoint> bindponit = pointEqipmentMapper.bind(o.toString());
            bind.put(o.toString(), bindponit);
            for (icDevPoint pointEquipment : bindponit) {

                fmRoominfo fmRoominfo = pointEqipmentMapper.selectfloorbydbid(pointEquipment.getDbid(), pointEquipment.getModelId());
                fmRoominfoMap.put(pointEquipment.getDbid(), fmRoominfo);
            }


        }
    }
//
//    @Scheduled(cron = "*/60 * * * * ?")
//    public void isnull() throws ParseException {
//        //判断数据库是否为空
//        List<SeRuleFile> seRuleFiles = fileMapper.selectAll();
//        if (seRuleFiles.size() == 0) {
//            kieHelper1 = new HashMap<>();
//        }
//    }

    @Scheduled(cron = "0 0 0 * * ?")
    private void aVoid() throws ParseException {
        this.data();
        Date nowData = new Date();
        if (isFirstin) {//第一次运行这个函数
            isFirstin = false;
            //记录现在的日期

            if (df.parse(df.format(nowData)).before(df.parse(time2)) && df.parse(df.format(nowData)).after(df.parse(time1))) {
                season = "/summer";
            } else {
                season = "/winter";
            }
            this.updatekieHepler();
            lastData = new Date();
        } else {//至少第二次运行这个函数，才判断是否跨天了
            //通过nowData和lastData判断是否跨天了
            if (!DateUtils.isSameDay(nowData, lastData)) {//如果跨天了
                this.updatekieHepler();

            } else {

            }

            //将现在日期交换到上次日期
            lastData = nowData;
        }
    }


    public void updatekieHepler() throws ParseException {
        //修改规则 可能绑定了 数据
        this.data();
        kieHelper1 = new HashMap<>();
        Date date = new Date();
        //根据日期和 是否显示查找文件
        if (df.parse(df.format(date)).before(df.parse(time2)) && df.parse(df.format(date)).after(df.parse(time1))) {
            season = "summer";
        } else {
            season = "winter";
        }

        // 查询 报警规则
        //List<SeRuleFile> seRuleFilesspace = fileMapper.selectAllbyseason("空间",season,"报警");
        List<SeRuleFile> seRuleFiles = fileMapper.selectAllbyseason(season, "报警");
        if (seRuleFiles.size() == 0) {
            kieHelper1 = new HashMap<>();
            //kieSession = null;
        } else {


            for (SeRuleFile seRuleFile : seRuleFiles) {
                KieHelper kieHelper = new KieHelper();

                try {
                    //获取规则文件
                    String dRl = KieSessionUtils.getDRl(upload + "/" + season + seRuleFile.getUrl());
                    KieHelper kieHelper2 = kieHelper.addContent(dRl, ResourceType.DRL);
                    if(seRuleFile.getWhethermatches().equals("实例")){
                        kieHelper1.put(seRuleFile.getFilename()+seRuleFile.getDbid(), kieHelper2);
                    }else {
                        kieHelper1.put(seRuleFile.getFilename(), kieHelper2);
                    }

                    //kieSession = kieHelper1.build().newKieSession();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    String[] split = deviceclose.split(",");
    static int i = 0;

    @SneakyThrows
    @Override
    public void run() {
        //测点
        String pointname = spotname;
        System.out.println(pointname);


        //获取开机存入的数据
        List<icDevPoint> pointNameList = bind.get(pointname.toString());
        List<String> Distinct = DistinctMap.get(pointname.toString());
        List<icPointVar> icVariables = icVariablesMap.get(pointname.toString());


        //查询 这个测点的最新数据
        String sql = "SELECT * FROM " + "\"" + pointname.toString() + "\" " + "  order by time desc limit " + (icVariables.size() - Distinct.size() + pointNameList.size());
        //  System.out.println(sql);
        if (sql != null) {

            QueryResult query = influxDBConnection.query(sql);


            List<QueryResult.Result> results = query.getResults();
            //循环获取数据将数据放进beanmap
            for (QueryResult.Result result : results) {
                List<QueryResult.Series> seriesList = result.getSeries();
                if (seriesList == null) {
                    break;
                } else {
                    int condition = 0;
                    //先判断是否有开关机 为0的情况
                    for (QueryResult.Series series : seriesList) {

                        List<String> columns = series.getColumns();
                        String[] keys = columns.toArray(new String[columns.size()]);
                        List<List<Object>> values = series.getValues();
                        for (List<Object> value : values) {
                            Map Beanmap = new HashMap<>();
                            for (int i = 0; i < keys.length; i++) {
                                Beanmap.put(keys[i], value.get(i));
                            }
                            //判断是否关机
                            if (condition == 1) {
                                break;
                            }
                            for (String s : split) {
//                                if (s.equals((String) Beanmap.get("vari_name"))) {
                                if (((String) Beanmap.get("vari_name")).equals(s)) {
                                    if (((String) Beanmap.get("value")).equals("0.0") || ((String) Beanmap.get("value")).equals("0.00")) {
                                        condition = 1;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    //开关机不为0 或者没有开关机
                    if (condition != 1) {

                        //查询这个测点绑定的数据  (取出这个测点绑定的全部数据)
                        List<icDevPoint> pointEquipments = bind.get(pointname.toString());
                        //如果 没有数据跳出
                        if (pointEquipments == null) {
                            break;
                        }

                        for (QueryResult.Series series : seriesList) {

                            List<String> columns = series.getColumns();
                            String[] keys = columns.toArray(new String[columns.size()]);
                            List<List<Object>> values = series.getValues();
                            for (List<Object> value : values) {
                                Map Beanmap = new HashMap<>();
                                for (int i = 0; i < keys.length; i++) {
                                    Beanmap.put(keys[i], value.get(i));
                                }

                                //用来判断
                                String value2 = (String) Beanmap.get("value");
                                String dbid = (String) Beanmap.get("dbid");
                                //如果都不为空 则说明绑定
                                if (StringUtils.isNotBlank(value2) && !dbid.equals("null")) {

                                    for (icDevPoint pointEquipment : pointEquipments) {

                                        //每个变量的内容
                                        //绑定的变量和循环的相同
                                        if (((String) Beanmap.get("vari_name")).equals(pointEquipment.getVarName())
                                                && pointEquipment.getDevName().equals(Beanmap.get("devName"))) {

                                            //房间和设备通用数据
                                            //如果相同说明是一条数据 用别名查询
                                            //如果为空
                                            DroolsTest droolsTest = new DroolsTest();
                                            if (StringUtils.isBlank(pointEquipment.getAliasVar())) {
                                                droolsTest.setKey(pointEquipment.getVarName());
                                            } else {
                                                droolsTest.setKey(pointEquipment.getAliasVar());
                                            }

                                            try {
                                                droolsTest.setValue(Float.valueOf((String) Beanmap.get("value")));
                                            } catch (Exception e) {
                                                break;
                                            }

                                            droolsTest.setDbId(Integer.valueOf((String) Beanmap.get("dbid")));
                                            droolsTest.setSingal((String) Beanmap.get("dbid"));

                                            //如果一条规则判断完成之后不关闭会导致 之后的规则全部能通过
                                            KieHelper kieHelper = null;

                                            if (pointEquipment.getDevNumber()!=null){
                                                kieHelper = kieHelper1.get(pointEquipment.getDevName() + " " + pointEquipment.getDevNumber()+pointEquipment.getDbid());
                                            }
                                            else {
                                                kieHelper =   kieHelper1.get(pointEquipment.getDevName()+" "+pointEquipment.getDbid());

                                            }
                                            if (kieHelper==null){
                                                kieHelper = kieHelper1.get(pointEquipment.getDevName());
                                            }
                                            //为空不执行
                                            if (kieHelper != null) {
                                                if (StringUtils.isBlank(pointEquipment.getDevNumber())) {
                                                    droolsTest.setPointName(pointEquipment.getDevName());
                                                } else {
                                                    droolsTest.setPointName(pointEquipment.getDevName() + " " + pointEquipment.getDevNumber());
                                                }
                                                KieSession kieSession = kieHelper.build().newKieSession();
//                                                Thread threads = threadHashMap.get(pointname);
                                                kieSession.insert(droolsTest);
                                                //执行
                                                kieSession.fireAllRules();
                                                this.push(droolsTest, pointname.toString(), null, pointEquipment.getModelId(), null,
                                                        null, null, null);

                                                kieSession.dispose();

                                            }
                                            //只有环境感知才走房间判断
                                            String subSpaRelations = pointEquipment.getDevGroup();
                                            if ("环境感知".equals(subSpaRelations) ||
                                                    "气体感知".equals(subSpaRelations)
                                            ) {
                                                //根据设备dbid 查询是否有房间
                                                fmRoominfo fmRoominfo = fmRoominfoMap.get(pointEquipment.getDbid());
                                                //fmRoominfo fmRoominfo = pointEqipmentMapper.selectfloorbydbid(droolsTest.getDbId(), pointEquipment.getModelId());
                                                if (fmRoominfo != null) {
                                                    //房间

                                                    if (fmRoominfo.getRmNumber() != null) {
                                                        droolsTest.setPointName(fmRoominfo.getRmName() + " " + fmRoominfo.getHouseNumber());
                                                    } else {
                                                        droolsTest.setPointName(fmRoominfo.getRmName());
                                                    }

                                                    KieHelper kieHelperroom = kieHelper1.get(droolsTest.getPointName()+fmRoominfo.getObjectId());

                                                    if (kieHelperroom != null) {

                                                        KieSession kieSession1 = kieHelperroom.build().newKieSession();
                                                        droolsTest.setSave(false);


                                                        kieSession1.insert(droolsTest);
                                                        //执行
                                                        kieSession1.fireAllRules();

                                                        //操作行为
                                                        this.push(droolsTest, pointname.toString(), fmRoominfo.getObjectId(),
                                                                fmRoominfo.getModelId(), fmRoominfo.getRmLevel(), fmRoominfo.getHouseNumber(),
                                                                fmRoominfo.getRmName(), subSpaRelations);

                                                        kieSession1.dispose();
                                                    }
                                                }
                                            }
                                            break;
                                        }

                                    }


                                }

                            }
                        }


                    }


                }
                Thread thread = threadHashMap.get(pointname);
                thread.stop();
            }
        }

    }

    //测试，晚点儿打开 要不要改成5秒一次  //执行完之后20秒
    @Scheduled(fixedDelay = 1000 * 10)
    public Result test() throws ParseException, MqttException, InterruptedException {
        if (kieHelper1.size() == 0) {
        } else {
            //所有测点
            for (Object pname : pointName) {
                spotname = pname.toString();
                //一个测点 运行一个线程
                Rundrools rundrools = new Rundrools();
                Thread thread = new Thread(rundrools);
                threadHashMap.put(pname.toString(), thread);
                thread.start();

                Thread.sleep(200);
            }
        }


//        //关闭
//        kieSession.dispose();
        return null;
    }

    //规则文件数据 点名 房间dbid modelid 房间楼层 房间编号
    public void push(DroolsTest droolsTest, String pointname, String dbid, String modelId, String level,
                     String number, String rmName, String subSpaRelations) throws Exception {
        //前端区分什么报警
        HashMap<Object, Object> alarmMap = new HashMap<>();
        String ordertype = null;
        String type = "dev";

        if (dbid != null) {
            ordertype = "环境安全提醒";
            type = "room";
        } else {
            ordertype = "设备" + droolsTest.getMessageType() + "提醒";
        }
//        if ("气体感知".equals(subSpaRelations)) {
////            ordertype = "危险气体提醒";
////        }

        //判断是否有规则通过
        if (droolsTest.getSave()) {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateString = formatter.format(new Date());
            //查询是否有这个报警信息
            //报警描述分割
            msgDevice alarm = new msgDevice();
            //用来自动复位的dbid存储
            String dbId = null;
            if (dbid != null) {
                alarm = alarmService.select(Integer.valueOf(dbid)
                        , droolsTest.getInformation(), modelId, droolsTest.getMessagelevel());
                dbId = dbid;
            } else {
                alarm = alarmService.select(droolsTest.getDbId()
                        , droolsTest.getInformation(), modelId, droolsTest.getMessagelevel());
                dbId = String.valueOf(droolsTest.getDbId());
            }

            HashMap<String, String> map = new HashMap<>();
            map.put("dbid", dbId);

            map.put("data", sdf01.format(new Date()));
            if (alarm == null) {

                //存储一条报警
                msgDevice add = this.add(droolsTest, dbid, modelId, level, number, subSpaRelations, 0);
                map.put("id", add.getId().toString());
                alarmhasMap.put(dbId + droolsTest.getKey() + modelId, map);
                alarmMessage alarmMessage = new alarmMessage();
                alarmMap.put("alarm", alarmMessage);
                //发送前端提醒
                WebSocketServerRemind.sendMessage(JSONArray.toJSONString(alarmMap));

            } else if (alarm != null && alarm.getAlarmCount() == 0) {

                long date = new Date().getTime();
                long alarmtime = sdf01.parse(alarm.getAlarmTime()).getTime();
                //如果报警时间小于当前时减5秒
                if ((alarmtime + 5000) < date && (alarmtime + 600000) < date) {
                    //可能是误报删除上一条数据 重新添加.
                    alarmMapper.delectbyid(alarm.getId());
                    msgDevice add = this.add(droolsTest, dbid, modelId, level, number, subSpaRelations, 0);
                    map.put("id", add.getId().toString());

                    alarmhasMap.put(dbId + droolsTest.getKey() + modelId, map);
                } else if ((alarmtime + 5000) < date) {

                    alarmMapper.delectbyid(alarm.getId());
                    icDevState state = infoMapper.selectStateByDbid(droolsTest.getDbId(), Integer.valueOf(modelId));

                    fmDevInfo fmDeviceinfo = infoMapper.selectdevicebyobjectId(String.valueOf(droolsTest.getDbId()), modelId);
                    //设备添加一次故障记录
                    if (alarm.getAlarmCount() == 0) {
                        infoMapper.updatedevicefo(fmDeviceinfo.getObjectId(), fmDeviceinfo.getFaultnumber() + 1);
                    }
                    if ("Good".equals(state.getSingal())) {
                        if (fmDeviceinfo != null) {
                            //修改报警次数
//                            msgDevice sendalarm = sendalarm(alarm, new Date(), droolsTest, type);
//                            if (sendalarm != null) {
//                                sendalarm.setAlarmValue(", 当前值为" + String.valueOf(droolsTest.getValue()));
//                                int update = alarmService.update(sendalarm);
//                            }
                            msgDevice msgDevice = this.add(droolsTest, dbid, modelId, level, number, subSpaRelations, 1);
                            map.put("id", msgDevice.getId().toString());
                            alarmhasMap.put(dbId + droolsTest.getKey() + modelId, map);
                            messageRemind messageRemind = new messageRemind();
                            messageRemind.setAlarmId(msgDevice.getId());
                            //不为null说明是房间报警
                            if (dbid != null) {
                                messageRemind.setDbId(Integer.parseInt(dbid));
                                messageRemind.setRmName(rmName+" "+number);
                                messageRemind.setHouseNumber(number);
                                messageRemind.setDevName(rmName+" "+number);
                                messageRemind.setRmLevel(level);
                                messageRemind.setLocation(rmName+" "+number);
                                messageRemind.setType("room");
                            } else {
                                messageRemind.setDbId(Integer.parseInt(fmDeviceinfo.getObjectId()));
                                //设备报警
                                messageRemind.setDevLocation(fmDeviceinfo.getDevLocation());
                                messageRemind.setDevName(fmDeviceinfo.getDevName());
                                messageRemind.setDevNumber(fmDeviceinfo.getDevNumber());
                                messageRemind.setType("dev");
                                if (StringUtils.isNotBlank(fmDeviceinfo.getDevLocation())) {
                                    messageRemind.setLocation(fmDeviceinfo.getDevLocation());

                                }
                            }
                            messageRemind.setOrderType(ordertype);
                            messageRemind.setFaultLevel(droolsTest.getMessagelevel());
                            messageRemind.setDescription(droolsTest.getInformation());
                            messageRemind.setLastrecialamtime(new Date());
                            messageRemind.setAlarmType("alarm");
                            messageRemind.setAlarmnumber(1);
                            messageRemind.setIsReset(false);
                            messageRemind.setModelId(Integer.parseInt(modelId));
                            messageRemind.setSubsystemBelong(fmDeviceinfo.getSubsystemBelong());
                            messageRemind.setSystemBelong(fmDeviceinfo.getSystemBelong());
                            messageRemind.setAlarmSatus(msgDevice.getAlarmStatus());
                            messageRemind.setAlarmVar(droolsTest.getKey());
                            //查询
                            messageRemind select = messageRemindMapper.selectbyfaultLevel(messageRemind);
//                            where  db_id = #{dbId}  and
//                            description=#{description} and fault_level=#{faultLevel}
//                            and model_id=#{modelId} and  order_type=#{orderType}
                            //如果没有这条消息
                            if (select == null) {
                                //消息提醒存储
                                messageRemindMapper.insertmessageRemind(messageRemind);
                            } else {
                                messageRemind.setId(select.getId());
                                messageRemindMapper.updatalarmnumberbyleve(messageRemind);

                            }

                            messagehasMap.put(dbId + droolsTest.getKey() + modelId, String.valueOf(messageRemind.getId()));
                            //临时使用
                            messageRemind.setDescription(messageRemind.getDescription() + ", 当前值:" + String.valueOf(droolsTest.getValue()));
                            HashMap<String, Object> cameramap = new HashMap<>();
                            //TODO
                            //判断是环境还是设备
                            if (dbid != null) {
                                cameramap.put("dbid", dbid);
                                cameramap.put("storey", droolsTest.getPointName().split(" ")[0]);
                                //websocket 发送这个设备属于哪个房间的流
                                List<Map<String, Object>> camera = new ArrayList<>();
                                List<fmDevInfo> dbidbyfloor = pointEqipmentMapper.dbidbyfloor(dbid, modelId);
                                for (fmDevInfo deviceinfo : dbidbyfloor) {
                                    List<icDevPoint> selectbydbid = pointEqipmentMapper.selectbydbid(deviceinfo.getObjectId(), modelId);
                                    for (icDevPoint pointEquipment : selectbydbid) {
                                        HashMap<String, String> maps = new HashMap<>();
                                        cameramap.put("ip", pointEquipment.getPointName());
                                        camera.add(cameramap);

                                    }

                                }
                                WebSocketServerCamera.sendMessage(JSONArray.toJSONString(camera));
                            }
                            alarmMessage alarmMessage = new alarmMessage();
                            alarmMap.put("alarm", alarmMessage);
                            //发送前端提醒
                            WebSocketServerRemind.sendMessage(JSONArray.toJSONString(alarmMap));
                            cameramap.put("data", messageRemind);
                            serviceMQTT.alarm(cameramap);
                        }


                    }

                }

            } else if (!"复位".equals(alarm.getAlarmStatus())) {

                msgDevice sendalarm = null;
                //如果不是复位 根据消息级别报警
                Date date = new Date();
                Date parse = sdf01.parse(alarm.getAlarmTime());

                alarmMessage alarmMessage = new alarmMessage();
                alarmMap.put("alarm", alarmMessage);


                if ("重要紧急".equals(alarm.getAlarmGrade())) {
                    if (alarm.getAlarmCount() <= 3) {
                        //比较是否相差一分钟
                        if ((60 * 1000) <= date.getTime() - parse.getTime()) {
                            alarm.setAlarmTime(sdf01.format(date));
                            sendalarm = sendalarm(alarm, date, droolsTest, type);
                            //WebSocketServerRemind.sendMessage(JSONArray.toJSONString(alarmMap));
                        }
                    }
                    // else if ((600 * 1000) <= date.getTime() - parse.getTime()) {
                    //     sendalarm = sendalarm(alarm, date, droolsTest, type);
                    //
                    // }
                } else if ("紧急".equals(alarm.getAlarmGrade())) {

                    if (alarm.getAlarmCount() <= 2) {
                        //比较是否相差5分钟
                        if ((60 * 1000) <= date.getTime() - parse.getTime()) {
                            sendalarm = sendalarm(alarm, date, droolsTest, type);
                            // WebSocketServerRemind.sendMessage(JSONArray.toJSONString(alarmMap));
                        }
                    }
                    // else if ((900 * 1000) <= date.getTime() - parse.getTime()) {
                    //     sendalarm = sendalarm(alarm, date, droolsTest, type);
                    //
                    // }
                } else if ("重要".equals(alarm.getAlarmGrade())) {

                    if (alarm.getAlarmCount() <= 2) {
                        //比较是否相差5分钟
                        if ((300 * 1000) <= date.getTime() - parse.getTime()) {
                            sendalarm = sendalarm(alarm, date, droolsTest, type);
                            // WebSocketServerRemind.sendMessage(JSONArray.toJSONString(alarmMap));
                        }
                    }
                    // else if ((900 * 1000) <= date.getTime() - parse.getTime()) {
                    //     sendalarm = sendalarm(alarm, date, droolsTest, type);
                    //
                    // }
                } else if ("一般".equals(alarm.getAlarmGrade())) {
                    //WebSocketServerRemind.sendMessage(JSONArray.toJSONString(alarmMap));
                    // if (alarm.getAlarmnumber() <= 3) {
                    //     //比较是否相差10分钟
                    //     if ((600 * 1000) <= date.getTime() - parse.getTime()) {
                    //         sendalarm = sendalarm(alarm, date, droolsTest, type);
                    //     }
                    // } else if ((1800 * 1000) <= date.getTime() - parse.getTime()) {
                    //     sendalarm = sendalarm(alarm, date, droolsTest, type);
                    //
                    // }
                }
                if (sendalarm != null) {
                    sendalarm.setAlarmValue(", 当前值:" + String.valueOf(droolsTest.getValue()));
                    int update = alarmService.update(sendalarm);
                }

            } else if ("复位".equals(alarm.getAlarmStatus())) {
                //如果是复位但还是报警
                alarm.setAlarmStatus(droolsTest.getMessageType());
                alarm.setAlarmCount(0);
                alarm.setAlarmTime(sdf01.format(new Date()));
                alarmService.update(alarm);
            } else {
                String description = alarm.getAlarmDescription();

                alarm.setAlarmTime(dateString);
                alarm.setAlarmValue(", 当前值:" + String.valueOf(droolsTest.getValue()));
                alarm.setIsNew(0);
                // alarm.setSingal(droolsTest.getSingal());
                alarm.setAlarmDescription(description);
                alarmService.update(alarm);
            }

        }
        //自动复位
        else {


            String alarmid = null;
            String messageid = null;
            String alarmdata =null;
            String dbId=null;
            if (dbid == null) {
                dbId= String.valueOf(droolsTest.getDbId());
//                HashMap<String, String> maps = (HashMap<String, String>) alarmhasMap.get(dbId + droolsTest.getKey() + modelId);
//                alarmid = maps.get("dbid");
//                alarmdata = maps.get("data");
//                messageid = (String) messagehasMap.get(dbId + droolsTest.getKey() + modelId);
//                alarmhasMap.remove(dbId + droolsTest.getKey() + modelId);
//                messagehasMap.remove(dbId + droolsTest.getKey() + modelId);
            } else {
                dbId=dbid;
//                HashMap<String, String> maps = (HashMap<String, String>) alarmhasMap.get(dbid + droolsTest.getKey() + modelId);
//                alarmid = maps.get(dbid);
//                alarmdata = maps.get("data");
//                messageid = (String) messagehasMap.get(dbid + droolsTest.getKey() + modelId);
//                alarmhasMap.remove(dbid + droolsTest.getKey() + modelId);
//                messagehasMap.remove(dbid + droolsTest.getKey() + modelId);
            }
            HashMap<String, String> maps = (HashMap<String, String>) alarmhasMap.get(dbId + droolsTest.getKey() + modelId);
            if (maps!=null){


            alarmid = maps.get("id");
            alarmdata = maps.get("data");


            if (alarmid != null &&  (new Date().getTime()-sdf01.parse(alarmdata).getTime()>3*24*60*60*1000)) {

                alarmhasMap.remove(dbId + droolsTest.getKey() + modelId);
                messagehasMap.remove(dbId + droolsTest.getKey() + modelId);
                String url = "http://" + ips + ":9032/MessageReset";
                HashMap<String, Object> map = new HashMap<String, Object>();
                if (messagehasMap!=null){
                    messageid = (String) messagehasMap.get(dbId + droolsTest.getKey() + modelId);
                }
                map.put("alarmId", alarmid);
                if (messageid!=null){
                    map.put("id", messageid);
                }else {
                    map.put("id", "0");
                }

                map.put("userId", "0");
                System.out.println(url);
                System.out.println(map);
                Object o = HttpClientUtil.formrequestPostUrl(url, map, null);

                System.out.println(o);

//                alarmhasMap.remove(dbid + droolsTest.getInformation() + modelId + droolsTest.getMessagelevel());

            }

            }
        }
    }

    public msgDevice sendalarm(msgDevice msgDevice, Date date, DroolsTest droolsTest, String type) throws MqttException {

        messageRemind messageRemind = new messageRemind();
        if (type.equals("room")) {
            messageRemind.setOrderType("环境安全提醒");
        } else {
            messageRemind.setOrderType("设备" + droolsTest.getMessageType() + "提醒");
        }
        messageRemind.setDbId(msgDevice.getDbId());
        messageRemind.setDescription(msgDevice.getAlarmDescription());
        messageRemind.setFaultLevel(msgDevice.getAlarmGrade());
        messageRemind.setModelId(Integer.parseInt(msgDevice.getModelId()));
        messageRemind select = messageRemindMapper.selectbyfaultLevel(messageRemind);
        select.setLastrecialamtime(date);
        messageRemindMapper.updatRemintime(select);
        msgDevice.setAlarmCount(msgDevice.getAlarmCount() + 1);
        msgDevice.setAlarmTime(sdf01.format(new Date()));


//        //发送消息
        HashMap<String, Object> map = new HashMap<>();

        select.setDescription(select.getDescription() + msgDevice.getAlarmValue());
        map.put("data", select);
//        msgDevice.setAlarmTime(sdf01.format(date));
//        msgDevice.setAlarmnumber(msgDevice.getAlarmnumber() + 1);
        // WebSocketServerRemind.sendMessage("alarm");
        serviceMQTT.alarm(map);
        return msgDevice;

    }

    public msgDevice add(DroolsTest droolsTest, String dbid,
                         String modelId, String level, String number,
                         String subSpaRelations, int conut) {

        msgDevice msgDevice = new msgDevice();
        icDevState state = infoMapper.selectStateByDbid(droolsTest.getDbId(), Integer.valueOf(modelId));
        //测点信号正常
        if (state != null && "Good".equals(state.getSingal())) {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateString = formatter.format(new Date());

            String modeId = pointEqipmentMapper.PointEquipmentbydbid(droolsTest.getDbId());
            fmDevInfo fmDeviceinfo = infoMapper.selectdevicebyobjectId(String.valueOf(droolsTest.getDbId()), modeId);
            if (fmDeviceinfo != null) {


                msgDevice.setAlarmValue(", 当前值:" + String.valueOf(droolsTest.getValue()));
                msgDevice.setAlarmTime(dateString);
                msgDevice.setIsNew(1);
                msgDevice.setIsHandle(0);
                msgDevice.setAlarmDescription(droolsTest.getInformation());
                msgDevice.setAlarmStatus(droolsTest.getMessageType());

                //  msgDevice.setComId(serComAddr.getAlarmFeatures());
                //为null 是设备


                if (dbid != null) {
                    msgDevice.setDevLocation(level);
                    msgDevice.setDevName(droolsTest.getPointName());
                    msgDevice.setAlarmType("环境安全提醒");
                    msgDevice.setDbId(Integer.valueOf(dbid));
                    msgDevice.setDevNumber(number);
                    msgDevice.setLevel(level);
                    msgDevice.setType("room");
                } else {
                    msgDevice.setDbId(droolsTest.getDbId());
                    if (fmDeviceinfo.getDevNumber()!=null){
                        msgDevice.setDevName(fmDeviceinfo.getDevName() + " " + fmDeviceinfo.getDevNumber());
                    }else {
                        msgDevice.setDevName(fmDeviceinfo.getDevName() );
                    }
                    msgDevice.setDevLocation(fmDeviceinfo.getDevLocation());
                    msgDevice.setDevNumber(fmDeviceinfo.getDevNumber());
                    msgDevice.setAlarmType("设备" + droolsTest.getMessageType() + "提醒");
                    msgDevice.setLevel(fmDeviceinfo.getDevLevel());
                    msgDevice.setType("dev");
                }
                if ("气体感知".equals(subSpaRelations)) {
                    msgDevice.setAlarmType("危险气体提醒");
                    msgDevice.setType("room");
                }
                //msgDevice.setVarId(serComAddr.getVariableId());
                msgDevice.setSystemName(fmDeviceinfo.getSystemBelong());
                msgDevice.setRemindType("微信提醒");
                msgDevice.setAlarmGrade(droolsTest.getMessagelevel());
                msgDevice.setMsgType("alarm");

                //  msgDevice.setVarType(serComAddr.getVariableType());
                //   msgDevice.setSingal(droolsTest.getSingal());
                msgDevice.setSubsystemName(fmDeviceinfo.getSubsystemBelong());

                msgDevice.setModelId(modelId);
                msgDevice.setAlarmCount(conut);
                msgDevice.setAlarmVar(droolsTest.getKey());
                alarmService.insertAlarm(msgDevice);

            }

        }
        return msgDevice;

    }
    @Scheduled(cron = "*/60 * * * * ?")
    public void msgdetection() throws ParseException {
        List<msgDevice> msg = alarmMapper.getbyalarmStatusandalarmCount();
        Date date = new Date();
        long time = date.getTime();
        for (msgDevice msgDevice : msg) {
            long alarmtime = sdf01.parse(msgDevice.getAlarmTime()).getTime();


            if ( (alarmtime + 300000) <= time) {
                msgDevice.setAlarmStatus("复位");
                alarmService.update(msgDevice);
            }
        }
    }
}
